import axios from "axios";
import type { AxiosRequestConfig, AxiosResponse } from "axios";
import { getToken, removeToken } from "@/utils/tokenOperate";
import globalMethods from "@/GlobalMethodProvider";
import globalConfig from "@/config";
import fso from "@/utils/FileOperate/operate";

const instance = axios.create({
  timeout: 1000 * 60
});

let errShowMessage = true;

instance.interceptors.request.use(
  config => {
    if (config.url) {
      config.url = globalConfig.proxy(config.url);
    }

    // 默认是显示错误提示
    // @ts-ignore
    if (typeof config.errShowMessage === "boolean") {
      // @ts-ignore
      errShowMessage = config.errShowMessage;
    } else {
      // @ts-ignore
      errShowMessage = !config.errShowMessage;
    }

    if (globalConfig.IS_DEBUG) {
      console.log("发送请求: ", config);
    } else {
      fso.info("发送请求: ", JSON.stringify(config, ["url", 'method', 'headers', 'data', 'params']));
    }
    return config;
  },
  (error: any) => {
    fso.info("request error: ", error);
    return Promise.reject(error);
  }
);

instance.interceptors.response.use(
  response => {
    if (globalConfig.IS_DEBUG) {
      console.log("请求响应: ", response.data);
    }

    const status = response?.data?.code || response?.data?.data?.code || response.status || 404;
    if (status !== 200) {
      const msg = response?.data?.msg || response?.data?.data?.msg || "系统异常";
      if (errShowMessage) {
        globalMethods.$error(msg);
      }
      return Promise.reject(response.data);
    } else if (status === 401) {
      if (errShowMessage) {
        globalMethods.$warning("太久没进行操作, 请重新登录");
      }

      // 清除 token
      removeToken();
      return Promise.reject(response.data);
    } else {
      return response.data;
    }
  },
  (error: any) => {
    fso.error("请求错误响应: ", error);

    console.log("response error: ", error);
    if (error.message === "Request failed with status code 401") {
      // 清除 token
      removeToken();
      if (errShowMessage) {
        globalMethods.$warning("太久没进行操作, 请重新登录");
      }
    } else {
      if (errShowMessage) {
        globalMethods.$error(error.message);
      }
    }
    return Promise.reject(error);
  }
);

// 因为本地缓存是异步的, 这里把 axios 封装一层来自动添加 token, 对应 axios()
type ProxyAxiosConfig = AxiosRequestConfig & {
  /** 当请求发生了错误, 则显示错误信息 */
  errShowMessage?: boolean;
};
const proxyAxios = (config: ProxyAxiosConfig): Promise<AxiosResponse<any, any>> => {
  return new Promise((resolve, reject) => {

    getToken()
      .then(token => {
        if (!token) console.log("此次请求没有token: ", config);

        if (config && config.headers) {
          const _token = config.headers.Authorization ? config.headers.Authorization : token;

          config.headers = {
            ...config.headers,
            Authorization: _token || "",
          };
        } else {
          config.headers = {
            Authorization: token || ""
          };
        }
        return instance(config);
      })
      .then(res => resolve(res))
      .catch(err => reject(err));
  });
};


export default proxyAxios;